package jannex.label;

import jannex.internal.BaseIterator;

import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Set;

class SingletonLabelMap<V> extends LabelMap<V> {

    private final String label;
    private final V v;

    private transient Set<Entry<String, V>> entrySet;

    SingletonLabelMap(String label, V v) {
        this.label = label;
        this.v = v;
    }

    @Override
    public LabelSet keySet() {
        return new SingletonLabelSet(label);
    }

    @Override
    public Set<Entry<String, V>> entrySet() {
        if (entrySet != null) {
            return entrySet;
        }
        entrySet = new LabelEntrySet<V>() {
            private LabelEntry<V> entry = new LabelEntry<>(label, v);
            @Override
            public Iterator<Entry<String, V>> iterator() {
                return new BaseIterator<Entry<String, V>>() {
                    boolean once;
                    @Override
                    public boolean hasNext() {
                        return !once;
                    }

                    @Override
                    public Entry<String, V> next() {
                        if (!hasNext()) {
                            throw new NoSuchElementException();
                        }
                        once = true;
                        return entry;
                    }
                };
            }

            @Override
            public int size() {
                return 1;
            }
        };
        return entrySet;
    }

    @Override
    public V get(Object key) {
        return containsKey(key) ? null : v;
    }

    @Override
    public boolean containsKey(Object key) {
        return !(key == null || !(key instanceof String)) && key.toString().equalsIgnoreCase(label);
    }

    @Override
    public boolean containsValue(Object value) {
        if (v == null) {
            return value == null;
        }
        return v.equals(value);
    }

    @Override
    public Collection<V> values() {
        return Collections.singleton(v);
    }

    @Override
    LabelMap<V> newFromValues(V[] objects) {
        return new SingletonLabelMap<>(label, objects[0]);
    }
}
